package com.link.play.fit.ai.ui.guide

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.View
import android.widget.SeekBar
import androidx.lifecycle.lifecycleScope
import com.link.play.fit.ai.R
import com.link.play.fit.ai.bean.UserGuide
import com.link.play.fit.ai.databinding.FgReachGoalBinding
import com.link.play.fit.ai.ui.guide.ac.GuidePbAc
import com.link.play.fit.ai.ui.weightcontrol.ac.WeighControlPbAc
import com.link.play.fit.ai.utils.LogX
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import java.text.DecimalFormat


class ReachGoalFg : BasePageFragment<FgReachGoalBinding>(FgReachGoalBinding::inflate) {

    var metricMin = 0.1f
    var metricMax = 1.5f

    val imperialLbsMin = 0.2f
    val imperialLbsMax = 3.0f


    lateinit var userGuideState: MutableStateFlow<UserGuide>

    @SuppressLint("SetTextI18n", "DefaultLocale")
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val df = DecimalFormat("0.0")

        when (val ac = requireActivity()) {
            is GuidePbAc -> {
                userGuideState = ac.viewModel.userGuideState
            }

            is WeighControlPbAc -> {
                userGuideState = ac.viewModel.userGuideState
            }

        }
        lifecycleScope.launch {
            userGuideState.collectLatest {
                when (it.goal) {
                    0 -> {
                        binding.tvSpeed.text = getString(R.string.gain_per_week)
                    }

                    2 -> {
                        binding.tvSpeed.text = getString(R.string.lose_per_week)
                    }
                }

                if (it.imperialMetric) {//kg
                    binding.seekBar.max = ((metricMax - metricMin) * 10).toInt()
                    binding.seekBar.progress = ((it.perWeightKg - metricMin) * 10).toInt()
                    binding.tvWeight.text = "${df.format(it.perWeightKg)} kg"
                    binding.tvMin.text = "$metricMin kg"
                    binding.tvMiddle.text = "${(metricMax - metricMin) / 2f + 0.1f} kg"
                    binding.tvMax.text = "$metricMax kg"
                    changeWenAn(perWeight = it.perWeightKg)
                } else {//lbs
                    binding.seekBar.max = ((imperialLbsMax - imperialLbsMin) * 10).toInt()
                    binding.seekBar.progress = ((it.perWeightLbs - imperialLbsMin) * 10).toInt()
                    binding.tvWeight.text = "${df.format(it.perWeightLbs)} lbs"
                    binding.tvMin.text = "$imperialLbsMin lbs"
                    binding.tvMiddle.text = "${(imperialLbsMax - imperialLbsMin) / 2f + 0.1f} lbs"
                    binding.tvMax.text = "$imperialLbsMax lbs"
                    changeWenAn(perImperialLbs = it.perWeightLbs)
                }
            }
        }

        binding.seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {

            override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit
            override fun onStopTrackingTouch(seekBar: SeekBar?) = Unit

            @SuppressLint("SetTextI18n")
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                var value = progress.toFloat() / 10f
                LogX.e(TAG, "value=$value")
                if (userGuideState.value.imperialMetric) {//kg
                    value += metricMin
                    userGuideState.update {
                        it.copy(
                            perWeightKg = value,
                            perWeightLbs = convertKgToLb(value)
                        )
                    }
                } else {//lbs
                    value += imperialLbsMin
                    userGuideState.update {
                        it.copy(
                            perWeightLbs = value,
                            perWeightKg = convertLbToKg(value)
                        )
                    }
                }
            }
        })
    }

    private fun changeWenAn(perWeight: Float? = null, perImperialLbs: Float? = null) {
        perWeight?.let {
            when (it) {
                in 0.1f..0.4f -> {
                    slowUI()
                }

                in 0.5..1.0 -> {
                    recommendedUI()
                }

                in 1.1..1.5 -> {
                    fastUI()
                }

            }
        }
        perImperialLbs?.let {
            when (it) {
                in 0.2f..1.0f -> {
                    slowUI()
                }

                in 1.1..2.0 -> {
                    recommendedUI()
                }

                in 2.1..3.0 -> {
                    fastUI()
                }

            }
        }
    }

    private fun slowUI() {
        binding.tv.text = getString(R.string.slow_and_steady)
        binding.ivWuGui.isSelected = true
        binding.ivTuzhi.isSelected = false
        binding.ivLaoYin.isSelected = false
    }

    private fun recommendedUI() {
        binding.tv.text = getString(R.string.recommended)
        binding.ivWuGui.isSelected = false
        binding.ivTuzhi.isSelected = true
        binding.ivLaoYin.isSelected = false
    }

    private fun fastUI() {
        binding.tv.text = getString(R.string.you_loose_skin)
        binding.ivWuGui.isSelected = false
        binding.ivTuzhi.isSelected = false
        binding.ivLaoYin.isSelected = true
    }

    private fun convertKgToLb(kg: Float): Float {
        // 1 kg = 2.20462 lb
        try {
            val lb = kg * 2.20462f
            val df = DecimalFormat("0.0") // 保留一位小数
            return df.format(lb).toFloat() // 格式化后转为 Float
        } catch (e: Exception) {
            return 0.0f
        }

    }

    private fun convertLbToKg(lb: Float): Float {
        // 1 lb = 0.453592 kg
        try {
            val kg = lb * 0.453592f
            val df = DecimalFormat("0.0") // 保留一位小数
            return df.format(kg).toFloat() // 格式化后转为 Float
        } catch (e: Exception) {
            return 0.0f
        }

    }

}